package com.itheima.springboot_21_j2cache.service.impl;

import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.springboot_21_j2cache.dao.BookDao;
import com.itheima.springboot_21_j2cache.domain.Book;
import com.itheima.springboot_21_j2cache.service.IBookService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class BookServiceImpl2 extends ServiceImpl<BookDao, Book> implements IBookService {
    @Autowired
    private BookDao bookDao;
    @Override
    public IPage<Book> getPage(int currentPage, int pageSize) {
        //System.out.println(currentPage+pageSize);
        IPage page=new Page(currentPage,pageSize);
        bookDao.selectPage(page,null);
        return page;
    }
    @Override
    public IPage<Book> getPage(int currentPage, int pageSize,String name) {
        LambdaQueryWrapper <Book> lqw=new LambdaQueryWrapper <Book> ();
        //lqw.like(String.isNotEmpty(book.getType()),Book::getType,book.getType());
        //lqw.like(String.isNotEmpty(book.getName()),Book::getName,book.getName());
        lqw.like(Strings.isNotEmpty(name),Book::getName,name);//Book::getName是数据对象对应的字段
        //lqw.like(String.isNotEmpty(book.getDescription()),Book::getDescription,book.getDescription());
        //System.out.println(currentPage+pageSize);
        IPage page=new Page(currentPage,pageSize);//page依赖MPConfig
        bookDao.selectPage(page,lqw);//后面是查询条件
        return page;
    }

    @Override
    @Cacheable(value="cacheSpace",key="#id") //表明这个查询用内存缓存,缓存变量是cacheSpace,缓存查询关键字是id,注意要有#号
    public Book getById(Integer id) {
        return bookDao.selectById(id);
    }

    @Override
    @Cacheable(value="cacheSpace",key="#id2") //表明这个查询用内存缓存,缓存变量是cacheSpace,缓存查询关键字是id2,注意要有#号
    public Integer testSetStringCache(Integer id,Integer id2,Integer id3) {
        return id;
    }
    //注意key一样,那么值类型要一样,否则新值无法替换老值,且程序会报错
    //还有个问题,我存在redis中的数据是Unicode的,程序员存进去的是明文,这是为什么?不知道 这是java序列化后的内容,取回去后还会反序列化的 老师没讲

    @CreateCache(name="jetCache_",expire = 3600,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.BOTH) //用这里,就要保证开启了jetcache @EnableCreateCacheAnnotation写在项目入口 3600过期时间1小时,
    private Cache<Integer,Integer> jetCache;
    //CacheType.LOCAL #指定缓存用本地还是远程
    //CacheType.REMOTE 默认这个
    //CacheType.BOTH #也可以在本地和远程都缓存
    @Override
    public Integer testJetCacheInteger (Integer id,Integer id2,Integer id3,Integer id4) {
        jetCache.put(id3,id3);//前面的id3是缓存中的key,后面的id3是这次操作的结果,这个结果是我模拟的,你也可以模拟成时间
        System.out.println(jetCache.get(id3));//根据key去缓存中取value
        return id;
    }

    @Override
    @Cached(name="jetCache2_",key="#id",expire = 3600,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.BOTH) //不用jetcache对象做缓存了,用spring的原始形式
    @CacheRefresh(refresh = 10) //为防止系统2修改mysql,本地缓存与redis和mysql不一致,10s去数据库查一次,进行更新 //还要防止缓存1000条,会一下查1000次,给数据库极大压力
    public Book testJetCacheInteger2 (Integer id, Integer id2, Integer id3, Integer id4, Integer id5) {
        return bookDao.selectById(id);
    }
    //CacheType.LOCAL #指定缓存用本地还是远程
    //CacheType.REMOTE 默认这个
    //CacheType.BOTH #也可以在本地和远程都缓存

    @Override
    @CacheUpdate(name="jetCache2_",key="#book.id",value = "#book")//注意key是形参的id,value是形参本身.还要注意,key和value都有＃井号
    public Boolean testJetCacheInteger2Update (Book book) {
        bookDao.updateById(book);
        return true;
    }

    @Override
    @CacheInvalidate(name="jetCache2_",key="#id")//注意key是形参的id.还要注意,key有＃井号 删除数据库会连同缓存一起删除掉
    public Integer testJetCacheInteger2Delete (Integer id) {
        return bookDao.deleteById(id);
    }
}
